﻿using Konveyer.Core;
using Konveyer.Core.Attributes;
using Konveyer.Core.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Konveyer.Example
{
    public static class ExampleFour
    {
        public static void Go()
        { 
            // all this is athe same as Example one 
            // get an instance provider and tell it about our widgets . Note the order is not important  
            var instanceProvider = Factory.GetInstanceProvider() ;
            instanceProvider.Register<ExampleFourWidget_1>(typeof(ExampleFourWidget_1));
            instanceProvider.Register<ExampleFourWidget_2>(typeof(ExampleFourWidget_2));
            instanceProvider.Register<ExampleFourWidget_3>(typeof(ExampleFourWidget_3));
            instanceProvider.Register<ExampleFourWidget_4>(typeof(ExampleFourWidget_4));

            // Get a Runner 
            var runner = Factory.GetRunner(instanceProvider);

            runner.WhenStarts(OnRequestStart);
            runner.WhenWidgetStarts(OnWidgetStart);
            runner.WhenWidgetEnds(OnWidgetEnd);
            runner.WhenEnds(OnRequestEnd);
            runner.WhenExceptionIsThrown(OnRequestException);

            // make a request to carry our data in and out 
            var request = new ExampleFourRequest();
           
            // execute a request
            runner.Execute(request) ;

            // view the result 
            Console.WriteLine("Result (Example 4): " + request.Greeting);

                      

            Console.WriteLine("Any key to continue");
            Console.ReadKey();
        }
             
              

        /* Listeners for runner */

        public static void OnRequestStart(IRequest req)
        {
            Console.WriteLine("The request has started");
        }

        public static void OnRequestEnd(IRequest req)
        {
            Console.WriteLine("The request has ended");
        }

        public static void OnRequestException(IRequest req)
        {
            Console.WriteLine("This Exception occured '" + req.Exception.Message + "' ");
        }

        private static void OnWidgetStart(IWidget widget, IRequest request)
        {
            Console.WriteLine(widget.GetType().Name + " Started");
            Console.WriteLine("on step " + request.CurrentStep);
        }

        private static void OnWidgetEnd(IWidget widget, IRequest request)
        {
            Console.WriteLine(widget.GetType().Name + " Ended");
            Console.WriteLine("on step " + request.CurrentStep);
        }
    } 


        // this says which widgets to use 
        [Belt(Step = OperationStep.DataLoading, Widget = typeof(ExampleFourWidget_1))]
        [Belt(Step = OperationStep.Validation, Widget = typeof(ExampleFourWidget_2))]
        [Belt(Step = OperationStep.Operation, Widget = typeof(ExampleFourWidget_3))]
        [Belt(Step = OperationStep.Logging, Widget = typeof(ExampleFourWidget_4))]

        class ExampleFourRequest : Konveyer.Core.Interfaces.IRequest
        {
            // these are inputs (name) and outputs (Greeting)
            public string Name { get; set; }
            public string Greeting { get; set; }
          
            public OperationStep CurrentStep { get; set; }
            public Exception Exception { get; set; } 
           
        }




        /// <summary>
        /// These widget dont do anything , they just let us see the listeners fire
        /// </summary>
        class ExampleFourWidget_1 : TypedWidget<ExampleFourRequest>
        {
            protected override void Do(ExampleFourRequest request)
            {

            }
        }

        /// <summary>
        /// These widget dont do anything , they just let us see the listeners fire
        /// </summary>
        class ExampleFourWidget_2 : TypedWidget<ExampleFourRequest>
        {
            protected override void Do(ExampleFourRequest request)
            {

            }
        }

        /// <summary>
        /// These widget dont do anything , they just let us see the listeners fire
        /// </summary>
        class ExampleFourWidget_3 : TypedWidget<ExampleFourRequest>
        {
            protected override void Do(ExampleFourRequest request)
            {
                if (request.Exception == null)
                {
                    request.Greeting = "Hello " + request.Name;
                }    
            }
        }

        /// <summary>
        /// These widget dont do anything , they just let us see the listeners fire
        /// </summary>
        class ExampleFourWidget_4 : TypedWidget<ExampleFourRequest>
        {
            protected override void Do(ExampleFourRequest request)
            {
                throw new Exception("hello from " + this.GetType().Name);
            }
        }
    
    }
